package repository

import (
	"context"
	"fmt"

	"rdiot-demo/internal/eav/domain"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// templateRepository TemplateRepository的实现
type templateRepository struct {
	db *gorm.DB
}

// NewTemplateRepository 创建模板仓储实例
func NewTemplateRepository(db *gorm.DB) TemplateRepository {
	return &templateRepository{
		db: db,
	}
}

// Create 创建模板
func (r *templateRepository) Create(ctx context.Context, template *domain.EntityTemplate) error {
	err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 1. 确保模板有ID
		if template.ID == uuid.Nil {
			template.ID = uuid.New()
		}

		// 创建模板
		if err := tx.Create(template).Error; err != nil {
			return fmt.Errorf("创建模板失败: %w", err)
		}

		// 2. 创建属性模板（一个一个创建，避免批量插入问题）
		if len(template.Attributes) > 0 {
			for i := range template.Attributes {
				template.Attributes[i].EntityTemplateID = template.ID
				// 确保每个属性都有唯一ID
				if template.Attributes[i].ID == uuid.Nil {
					template.Attributes[i].ID = uuid.New()
				}
				
				// 检查ID是否已存在
				var existingCount int64
				if err := tx.Model(&domain.AttributeTemplate{}).Where("id = ?", template.Attributes[i].ID).Count(&existingCount).Error; err != nil {
					return fmt.Errorf("检查属性ID失败 [%s]: %w", template.Attributes[i].Name, err)
				}
				if existingCount > 0 {
					// 如果ID已存在，重新生成
					template.Attributes[i].ID = uuid.New()
				}
				
				// 单独创建每个属性
				if err := tx.Create(&template.Attributes[i]).Error; err != nil {
					return fmt.Errorf("创建属性模板失败 [%s]: %w", template.Attributes[i].Name, err)
				}
			}
		}

		return nil
	})

	return err
}

// GetByID 根据ID获取模板
func (r *templateRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.EntityTemplate, error) {
	var template domain.EntityTemplate
	err := r.db.WithContext(ctx).
		Preload("Attributes").
		Where("id = ?", id).
		First(&template).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, gorm.ErrRecordNotFound
		}
		return nil, fmt.Errorf("获取模板失败: %w", err)
	}

	return &template, nil
}

// GetByName 根据名称获取模板
func (r *templateRepository) GetByName(ctx context.Context, name string) (*domain.EntityTemplate, error) {
	var template domain.EntityTemplate
	err := r.db.WithContext(ctx).
		Preload("Attributes").
		Where("name = ?", name).
		First(&template).Error

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, gorm.ErrRecordNotFound
		}
		return nil, fmt.Errorf("根据名称获取模板失败: %w", err)
	}

	return &template, nil
}

// Update 更新模板
func (r *templateRepository) Update(ctx context.Context, template *domain.EntityTemplate) error {
	err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 1. 更新模板基本信息
		if err := tx.Save(template).Error; err != nil {
			return fmt.Errorf("更新模板失败: %w", err)
		}

		// 2. 删除旧的属性模板
		if err := tx.Where("entity_template_id = ?", template.ID).Delete(&domain.AttributeTemplate{}).Error; err != nil {
			return fmt.Errorf("删除旧属性模板失败: %w", err)
		}

		// 3. 创建新的属性模板
		if len(template.Attributes) > 0 {
			for i := range template.Attributes {
				template.Attributes[i].EntityTemplateID = template.ID
			}
			if err := tx.Create(&template.Attributes).Error; err != nil {
				return fmt.Errorf("创建新属性模板失败: %w", err)
			}
		}

		return nil
	})

	return err
}

// Delete 删除模板
func (r *templateRepository) Delete(ctx context.Context, id uuid.UUID) error {
	err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 1. 删除属性模板
		if err := tx.Where("entity_template_id = ?", id).Delete(&domain.AttributeTemplate{}).Error; err != nil {
			return fmt.Errorf("删除属性模板失败: %w", err)
		}

		// 2. 删除模板
		if err := tx.Delete(&domain.EntityTemplate{}, "id = ?", id).Error; err != nil {
			return fmt.Errorf("删除模板失败: %w", err)
		}

		return nil
	})

	return err
}

// List 查询模板列表
func (r *templateRepository) List(ctx context.Context, filter TemplateFilter) ([]domain.EntityTemplate, int64, error) {
	db := r.db.WithContext(ctx).Model(&domain.EntityTemplate{})

	// 应用过滤条件
	if filter.Name != "" {
		db = db.Where("name LIKE ?", "%"+filter.Name+"%")
	}
	if filter.IsActive != nil {
		db = db.Where("is_active = ?", *filter.IsActive)
	}

	// 计算总数
	var total int64
	if err := db.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("统计模板数量失败: %w", err)
	}

	// 分页查询
	var templates []domain.EntityTemplate
	offset := (filter.Page - 1) * filter.Size
	err := db.Preload("Attributes").
		Limit(filter.Size).
		Offset(offset).
		Find(&templates).Error

	if err != nil {
		return nil, 0, fmt.Errorf("查询模板列表失败: %w", err)
	}

	return templates, total, nil
}
